#include "fsm.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

int fsm_init(fsm_t **my_fsm, int rfd, int wfd)
{
	int save;

	*my_fsm = malloc(sizeof (fsm_t));
	if (NULL == *my_fsm)
		return -1;
	(*my_fsm)->rfd = rfd;
	(*my_fsm)->wfd = wfd;
	(*my_fsm)->state = STATE_R;
	memset((*my_fsm)->buf, '\0', BUFSIZE);
	(*my_fsm)->read_cnt = (*my_fsm)->pos = 0;
	(*my_fsm)->errmsg = NULL;

	save = fcntl((*my_fsm)->rfd, F_GETFL);
	fcntl((*my_fsm)->rfd, F_SETFL, save | O_NONBLOCK);

	save = fcntl((*my_fsm)->wfd, F_GETFL);
	fcntl((*my_fsm)->wfd, F_SETFL, save | O_NONBLOCK);

	return 0;
}

int fsm_drive(fsm_t *my_fsm)
{
	int ret;

	switch (my_fsm->state) {
		case STATE_R: // 读状态
			my_fsm->read_cnt = read(my_fsm->rfd, my_fsm->buf, BUFSIZE);
			if (-1 == my_fsm->read_cnt) {
				if (EAGAIN == errno) {
					;
				} else {
					my_fsm->state = STATE_E;
					my_fsm->errmsg = "Error reading file";
				}
			} else if (0 == my_fsm->read_cnt) {
				my_fsm->state = STATE_T;
			} else {
				my_fsm->state = STATE_W;
				my_fsm->pos = 0;
			}
			break;
		case STATE_W: // 写状态
			ret = write(my_fsm->wfd, my_fsm->buf + my_fsm->pos, my_fsm->read_cnt);

			if (-1 == ret) {
				my_fsm->state = STATE_E;
				my_fsm->errmsg = "Error writing to file";
			} else if (ret < my_fsm->read_cnt) { // 没写完
				my_fsm->read_cnt -= ret;
				my_fsm->pos += ret;
			} else {
				my_fsm->state = STATE_R;
			}
			break;
		case STATE_E: // 错误状态
			perror(my_fsm->errmsg);
			my_fsm->state = STATE_T;
			break;
		case STATE_T: // 结束状态
		default:
			break;
	}
}

int fsm_destroy(fsm_t **my_fsm)
{
	free(*my_fsm);
	*my_fsm = NULL;
}

